package sky;


import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.ApplicationContext;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.deploy.NamingResourcesImpl;
import org.apache.catalina.startup.Tomcat;
import sky.JULLog.MyLogger;
import sky.controller.HelloController;
import sky.listener.ShutdownListener;
import sky.valve.LogValve;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.logging.Logger;

public final class Application {


    private static Logger log = MyLogger.getLogger(Application.class);

    private File tmpDir = new File(System.getProperty("user.dir") + "/tomcat");

    private Tomcat tomcat = new Tomcat();


    private void init() throws Throwable {

        if (!tmpDir.exists()) {
            tmpDir.mkdirs();
        }

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                    try {
                        tomcat.destroy();
                    } catch (LifecycleException e) {
                        e.printStackTrace();
                    }
                })
        );
        load();
    }

    private void load() throws Throwable {

        tomcat.setSilent(false);    //打印 info日志

        tomcat.setBaseDir(tmpDir.getAbsolutePath()); // 设置工作目录

        tomcat.setHostname("sky-localhost");    // 主机名, 将生成目录: {工作目录}/work/Tomcat/{主机名}/ROOT


        /*获取一个server */
        Server server = tomcat.getServer();
        server.init();

        server.setGlobalNamingResources(new NamingResourcesImpl());

//        server.setShutdown("shutdown");
        server.setPortOffset(8005);

        log.info("工作目录: " + server.getCatalinaBase().getAbsolutePath());

        /*获取默认  service */
        Service service = server.findServices()[0];
        service.setName("tomcat单实例service");
        server.addService(service);//可以但没必要, server中的service数量+1, 而且两个service都是一样的 ;

        /*设置一个 engine */
        Engine engine = new StandardEngine();
        engine.setDefaultHost("localhost");
        engine.setName("ApplicationEngine");
        service.setContainer(engine);
//        ((StandardEngine) engine).addValve(new LogValve());


        /*设置一个 host */
        StandardHost host = new StandardHost();
        host.setName("localhost");
        engine.addChild(host);




        /* 设置一个连接器 */
        //tomcat.setPort(80);
        Connector connector = tomcat.getConnector();
        connector.setPort(80);


        // contextPath要使用的上下文映射，""表示根上下文
        // docBase上下文的基础目录，用于静态文件。相对于服务器主目录必须存在 ({主目录}/webapps/{docBase})         todo 应该由 host 去添加 context
        StandardContext context = (StandardContext) tomcat.addContext(host, "/sky", /*{webapps}/~*/ "/ROOT");

        context.setName("oa3-web应用");//先执行 addServlet 方法,  才会去 创建对象
        Tomcat.addServlet(context, "globalServlet", new HttpServlet() {
            private static final long serialVersionUID = 1L;

            @Override
            protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                response.setCharacterEncoding("UTF-8");
                response.setContentType("text/plain");
                response.setHeader("Server", "Embedded Tomcat");
                try (Writer writer = response.getWriter()) {
                    writer.write("Hello, Embedded Tomcat!");
                    writer.flush();
                }
            }

            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                log.info("globalServlet........");
                super.doGet(req, resp);
            }


            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                log.info("globalServlet........");

                super.doPost(req, resp);
            }
        });

        Tomcat.addServlet(context, HelloController.class.getName(), new HelloController());

        context.addServletMappingDecoded("/", "globalServlet");
        context.addServletMappingDecoded("/hello", HelloController.class.getName());
        /*设置一个 ShutdownListener  被阉了一刀 ,  想用得自己配置  */
        context.getServletContext().addListener("ShutdownListener");


        tomcat.start();
        log.info("tomcat 已启动 ==> " + server.getAddress() + ":" + server.getPort());
        tomcat.getServer().await();

    }


    public static void main(String[] args) throws Throwable {
        new Application().init();
    }


}
